import React from 'react';
import ResizeableTitle from './ResizeableTitle';
import { Table } from 'antd';
import styles from './index.module.less';
import BaseComp from '../Base/BaseComp';
import {
    filter, find,
    findIndex,
    forEach, forIn,
    indexOf,
    isArray,
    isEmpty,
    isEqual,
    isFunction, isNumber,
    isObject, isUndefined,
    map,
    omit, pick, trim,
} from 'lodash-es';
import SumRow from './SumRow';
import { EditableCell, EditableRow } from './EditableRowCell';
import {
    isNotEmpty,
    getRandomKey,
    isObjectValEqual,
    isObjectValueEmpty,
    recursiveMap,
    jhAdd, recursiveFind, isModernBrowser
} from 'jh-utils';
import PropTypes from 'prop-types';
import keyCodes from '../../keyCodes';
import isString from 'lodash-es/isString';
import { ComponentType, TableBarActions } from '../Config';
import { hadInnerDataIndex } from './helper';

/**
 * 当前是否“现代浏览器”
 */
let isCurModernBrowser = isModernBrowser();

const NoCol = {
    title: '序号',
    dataIndex: 'NO',
    width: 50,
    align: 'center',
    fixed: 'left',
};

const defaultFields = ['key', 'lineKey'];

function genCellRefKey({ row, col }) {
    return `ref_${row}_${col}`;
}

function genRecordByCols(columns) {
    const obj = {};
    forEach(columns, (col) => {
        if (col && col.dataIndex && col.dataIndex.indexOf('.') === -1) {
            obj[col.dataIndex] = col.componentType === ComponentType.CHECK_BOX ? false : null;
        }
    });
    obj.key = getRandomKey();
    if (isUndefined(obj.lineKey)) {
        obj.lineKey = obj.key;
    }
    return obj;
}

function getStyle(obj, attr) {
    if (obj.currentStyle) {
        return obj.currentStyle[attr];
    } else {
        return document.defaultView.getComputedStyle(obj, null)[attr];
    }
}

function dealData(data) {
    return map(data, (item, ind) => {
        if (!isObject(item)) return item;
        let newItem = { ...item };
        if ('undefined' === typeof item.key) {
            newItem.key = item.id || getRandomKey();
        }
        if (isUndefined(newItem.lineKey)) {
            newItem.lineKey = getRandomKey();
        }
        return newItem;
    });
}

/**
 * 将 targetDom 元素滚动到 containDom 的可见区域
 * @param containDom {HTMLElement}
 * @param targetDom {HTMLElement}
 * @param leftFixedWidth {number} containDom 元素中，左侧冻结宽度
 * @param rightFixedWidth {number} containDom 元素中，右侧冻结宽度
 */
function scroll2View(containDom, targetDom, leftFixedWidth = 0, rightFixedWidth = 0) {

    if (containDom && targetDom && isFunction(containDom.scrollBy)) {
        let sx = 0;
        let sl = containDom.scrollLeft; // 左侧已滚动的宽度
        let cw = containDom.offsetWidth; // 可见的宽度
        // let sw = containDom.scrollWidth; // 可滚动的总宽度

        let l = targetDom.offsetLeft;
        let w = targetDom.offsetWidth;

        if (l < sl + leftFixedWidth) { // targetDom 被左侧遮盖，则 targetDom 需要向右移动，滚动条向左滚动
            sx = -(sl + leftFixedWidth - l);

        } else if (l - sl + w > cw - rightFixedWidth) {// targetDom 被右侧遮盖，则 targetDom 需要向左移动，滚动条向右滚动
            sx = l - sl + w - (cw - rightFixedWidth);
        }
        if (sx !== 0) {
            containDom.scrollBy(sx, 0);
        }
    }
}

export default class TableBase extends BaseComp {

    static propTypes = {
        /**
         * 列配置
         */
        colsConf: PropTypes.arrayOf(PropTypes.object),
        /**
         * 操作配置，数据结构如下：
         * {
              "addable": boolean, // 可添加
              "deletable": boolean, // 可删除
              "editable": boolean, // 可编辑
              "required": boolean, // 不能为空，至少有一条数据
              "keyField": string, // 关键字段名。比如 keyField: "item"，则当某条数据的"item"字段不为空时，才作为有效数据，否则不取出这条数据
            }
         */
        actionConf: PropTypes.object,
        /**
         * 单元格数据有变化时的回调
         * @param dataIndex
         * @param newRecord
         * @param oldRecord
         * @param rowIndex
         * @param params
         * @return object | boolean 返回 false 可阻止本次更新
         * @type {function(dataIndex:string, newRecord: {}, oldRecord:{}, rowIndex:number, params: {list: [{}]})}
         */
        onCellUpdate: PropTypes.func,
        /**
         * @param params object 参数结构如下：
         * {
                type: key,
                record: record,
                rowIndex: tempArr[curIndex] ? tempArr[curIndex].key : '',
                dataList: 更新后的 dataSource,
                preDataList: 更新前的 dataSource,
            }
         * @return array | boolean 返回 false 可阻止本次更新
         */
        onRowUpdate: PropTypes.func,
        /**
         *
         * @param item
         * @return {*}
         */
        getDefaultRecord: PropTypes.func,
        // 是否需要“序号”列
        needNO: PropTypes.bool,
        // 是否可移动行
        canSort: PropTypes.bool,
        canDel: PropTypes.bool,
        autoAdd: PropTypes.bool,
        // 是否显示左侧 checkbox
        rowSelect: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
        // 汇总数据；每一列的字段名与 columns 的 dataIndex 对应
        sumData: PropTypes.arrayOf(PropTypes.object),
        /**
         *  调整列宽时的回调
         * @param data { width: number, height: number }
         * @param colInd number
         * @return {*} void
         */
        onResize: PropTypes.func,
        /**
         * 表格单元格是否可编辑的标识。
         * 以 dataIndex 为 key，以 function或boolean 为 value
         */
        fieldEnabledObj: PropTypes.object,
        /**
         * 默认有多少行
         */
        defaultRowCnt: PropTypes.number,
    };

    static getDerivedStateFromProps(nextProps, prevState) {
        const newState = {};

        if (!isObjectValEqual(nextProps, {
            dataSource: prevState.propData,
        }, ['dataSource'])) {
            let dataSource = dealData(nextProps.dataSource);
            let defaultRowCnt = parseInt(nextProps['defaultRowCnt']);
            let len = dataSource.length;

            if (defaultRowCnt > 0 && len === 0) {
                let restLen = defaultRowCnt - len;

                if (restLen > 0) {
                    for (let i = 0; i < restLen; i++) {
                        dataSource.push({ key: getRandomKey() });
                    }
                }
            }

            newState.dataSource = dataSource;
            newState.propData = nextProps.dataSource;
            newState.originData = nextProps.dataSource;
        }

        if (!isObjectValEqual(nextProps, {
            columns: prevState.propCols,
        }, ['columns'])) {
            let nextCol = nextProps.columns || [];
            let newCols = nextProps.needNO ? [{
                ...NoCol,
                title: window.localUtils && window.localUtils.formatMsgByCn ?
                    window.localUtils.formatMsgByCn(NoCol.title) : NoCol.title,
            }, ...nextCol] : nextCol;

            newState.columns = newCols;
            newState.propCols = nextProps.columns;
        }
        return isEmpty(newState) ? null : newState;
    }

    components = {
        header: {
            cell: ResizeableTitle,
        },
        body: {
            row: EditableRow,
            cell: EditableCell,
        },
    };

    tfootRef = React.createRef();

    editableCols = []; // 可编辑的列；用于辅助快捷键的实现
    rowRefs = {}; // 用于保存 EditableRow 的实例
    editableCellRefs = {}; // 用于保存 EditableCell 可编辑的单元格实例
    focusRow = ''; // 当前选定的行索引
    editingCell = { // 正在编辑的单元格索引
        row: '',
        col: '',
    };
    changedRecords = {}; // 有值发生改变的记录
    deletedIds = []; // 删除了的记录
    /**
     * 可拖拽表头的宽度
     * @type {{[_colIndex]: number|string}}
     */
    resizingColsW = {};

    scrollObj = {};
    tableID = `jh-${getRandomKey()}`;
    tableDom = null;
    tableBody = null;

    initState(props) {
        let cols = props.columns || [];
        let newCols = props.needNO ? [{
            ...NoCol,
            title: this.formatMsgByCn(NoCol.title),
        }, ...cols] : cols;
        let dataSource = dealData(props.dataSource);
        let defaultRowCnt = parseInt(props['defaultRowCnt']);
        let len = dataSource.length;

        if (defaultRowCnt > 0 && len === 0) {
            let restLen = defaultRowCnt - len;

            if (restLen > 0) {
                for (let i = 0; i < restLen; i++) {
                    dataSource.push({ key: getRandomKey() });
                }
            }
        }

        return {
            ...super.initState(props),
            columns: newCols,
            propCols: this.props.columns,
            dataSource: dataSource,
            propData: this.props.dataSource,
            originData: this.props.dataSource,
            tableRandomKey: getRandomKey(),
        };
    }

    componentDidMount() {
        super.componentDidMount && super.componentDidMount();
        this.refreshTDom();
        // console.log('this.tableDom', this.tableDom)
        this._setScrollTBody();
    }

    componentDidUpdate(prevProps, prevState) {
        super.componentDidUpdate && super.componentDidUpdate(prevProps, prevState);

        if (prevState.tableRandomKey !== this.state.tableRandomKey) {
            this.refreshTDom();
        }

        this._setScrollTBody();
    }

    /**
     * 重置“用于标识 表格有数据变化”的变量
     */
    resetModify() {
        this.changedRecords = {}; // 有值发生改变的记录
        this.deletedIds = []; // 删除了的记录
    }

    /**
     * 刷新表格 dom 元素，用于从新计算表格高度
     */
    refreshTDom() {
        const domList = document.getElementsByClassName(this.tableID);
        if (domList && domList[0]) {
            this.tableDom = domList[0];
        }
    }

    /**
     * 找到可横向滚动的table-body
     * @private
     */
    _setScrollTBody() {
        const { style = {} } = this.props;
        const { height } = style;

        // 找到可横向滚动的table-body
        if (this.tableDom && this.tableDom.getElementsByClassName && this.scrollObj) {

            if (this.scrollObj.x > 0) { // 有横向滚动时，获取滚动区域的 dom，用于手动控制滚动位置
                // 表头固定，则往下找 'ant-table-body'
                let tbodyList = this.tableDom.getElementsByClassName('ant-table-body');

                if (isEmpty(tbodyList) || isEmpty(tbodyList[0])) { // 表头不固定，则往下找 'ant-table-content'
                    tbodyList = this.tableDom.getElementsByClassName('ant-table-content');
                }
                if (tbodyList && tbodyList[0]) {
                    this.tableBody = tbodyList[0];

                    if (this.tableBody.classList && -1 === this.tableBody.classList.value.indexOf('ant-table-content')
                        && -1 === this.tableBody.classList.value.indexOf('ant-table-body')) {
                        this.tableBody = null;
                    }
                }
            }
            // if (this.tableBody) {
            //     console.log('------------', this.tableBody.classList.value, this.tableBody.classList && -1 === this.tableBody.classList.value.indexOf('ant-table-content')
            //         && -1 === this.tableBody.classList.value.indexOf('ant-table-body'))
            // }
            // this.tableBody 的纵向滚动高度 = this.tableDom.offsetHeight - ('.ant-table-header' 的高度) - ('.ant-pagination' 的高度)
            if (this.tableBody && this.tableBody.style && height !== 'auto') {
                let hDom = this.tableDom.getElementsByClassName('ant-table-header')[0];

                let pDom = this.tableDom.getElementsByClassName('ant-pagination')[0];
                let sY = this.tableDom.offsetHeight - 2;

                if (hDom) { // 表头节点
                    hDom.style.maxHeight = 'none';
                    hDom.style.height = 'auto';
                    sY -= hDom.offsetHeight;
                }

                if (pDom) { // 分页节点
                    let mt = parseInt(getStyle(pDom, 'marginTop')) || 5;
                    sY -= pDom.offsetHeight + mt * 2;
                }
                this.tableBody.style.height = this.tableBody.style.maxHeight = `${sY}px`;
            }
        }
    }

    // initData(data, afterCb) {
    //     this.changedRecords = {};
    //     const newList = map(data, (item) => (
    //         item && 'undefined' === typeof item.key ? {...item, key: (item.id || getRandomKey())} : item
    //     )) || [];
    //     const newState = {
    //         dataSource: newList,
    //         originData: newList
    //     };
    //
    //     if (reMountTable) {
    //         /**
    //          * 用于保存 EditableCell 可编辑的单元格实例。
    //          * 由于重新设置了 state.tableRandomKey 会导致 Table 重载，所以在这里把 editableCellRefs 重置
    //          * @type {{}}
    //          */
    //         this.editableCellRefs = {};
    //         newState.tableRandomKey = getRandomKey();
    //     }
    //
    //     this.setState(newState, afterCb);
    // }

    /**
     * 设置表格数据
     * @param data
     * @param afterCb
     * @param reMountTable {boolean} 是否需要重载 Table。默认 false
     * @param isInit {boolean} 是否初始化，如果是，则添加 defaultRowCnt 相关逻辑
     */
    setData(data, afterCb, reMountTable = false, isInit = false) {
        // console.log('setData');
        this.changedRecords = {};
        const newList = dealData(data);
        let dataSource;

        if (isInit) {
            dataSource = [...newList];
            let defaultRowCnt = parseInt(this.getPropsByName('defaultRowCnt'));
            let len = dataSource.length;

            if (len === 0 && defaultRowCnt > 0) {
                let restLen = defaultRowCnt - len;

                if (restLen > 0) {
                    for (let i = 0; i < restLen; i++) {
                        dataSource.push({ key: getRandomKey() });
                    }
                }
            }
        } else {
            dataSource = newList;
        }
        const newState = {
            dataSource: dataSource,
            originData: newList,
        };

        if (reMountTable) {
            /**
             * 用于保存 EditableCell 可编辑的单元格实例。
             * 由于重新设置了 state.tableRandomKey 会导致 Table 重载，所以在这里把 editableCellRefs 重置
             * @type {{}}
             */
            this.editableCellRefs = {};
            newState.tableRandomKey = getRandomKey();
        }

        this.setState(newState, afterCb);

    }

    /**
     * 将 data 数据排到前面，空行移到后面
     * @param data {[object]} 需要排到前面的数据列表
     * @param afterCb
     */
    refreshWithEmptyRow(data, afterCb) {
        let dataSource = [...(data || [])];
        let len = dataSource.length;
        let curDataLen = this.state.dataSource.length;

        if (curDataLen > 0) {
            let restLen = curDataLen - len;

            if (restLen > 0) {
                for (let i = 0; i < restLen; i++) {
                    dataSource.push({ key: getRandomKey() });
                }
            }
        }

        if (curDataLen !== len) {
            this.setDataSource(dataSource, afterCb);
        } else {
            afterCb && afterCb();
        }
    }

    /**
     * 更新某条记录的值。可指定更新哪些字段
     * @param record
     * @param updateFields {[string]} 需要更新的字段数组。如果为空，则更新 record 的所有字段
     * @param afterCb
     */
    updateRecordFields(record, updateFields = [], afterCb = null) {
        if (record.key) {
            let obj;
            const changedRecord = this.changedRecords[record.key] || {};
            const tmpRecord = isEmpty(updateFields) ? record : pick(record, updateFields);

            if (changedRecord) {
                obj = { ...changedRecord, ...tmpRecord };
            } else {
                obj = tmpRecord;
            }
            this.changedRecords[record.key] = { ...obj, CHANGED: true };

            this.setDataSource(this.state.dataSource, afterCb);

        } else {
            afterCb && afterCb();
        }
    }

    getDefaultRecord(record) {
        const { getDefaultRecord } = this.props;
        const { columns } = this.state;
        return isFunction(getDefaultRecord) && getDefaultRecord({ ...record }) || genRecordByCols(columns);
    }

    /**
     * 获取表格数据
     * @param onlyChange 只取有变化的值。默认 true
     * @param options
     * @return {[]}
     */
    getAjaxData(onlyChange = true, options = {}) {
        const { noEmpty } = options || {};
        const actionConf = this.getPropsByName('actionConf') || {};
        const reData = [];

        if (onlyChange) {// 只取有变化的值

            forEach(this.state.dataSource, (dataItem) => {
                const changedRecord = this.changedRecords[dataItem.key];
                let obj;

                if (!isEmpty(changedRecord)) {
                    obj = { ...dataItem, ...changedRecord };

                } else if (dataItem && (dataItem.CHANGED || !(dataItem.id > 0))) {

                    if (changedRecord) {
                        obj = { ...dataItem, ...changedRecord };
                    } else {
                        obj = dataItem;
                    }
                }

                if (obj && (
                    true !== noEmpty || (
                        !isEmpty(omit(obj, defaultFields)) && (isEmpty(actionConf.keyField) || isNotEmpty(obj[actionConf.keyField]))
                    )
                )) {
                    if (isUndefined(obj.lineKey)) {
                        obj.lineKey = obj.key;
                    }
                    reData.push(obj);
                }

            });

        } else { // 取当前列表的所有值
            forEach(this.state.dataSource, (dataItem) => {
                let obj;
                const changedRecord = this.changedRecords[dataItem.key];

                if (changedRecord) {
                    obj = { ...dataItem, ...changedRecord };

                } else if (dataItem) {
                    obj = { ...dataItem };
                }

                if (obj && (
                    true !== noEmpty || (
                        !isEmpty(omit(obj, defaultFields)) && (isEmpty(actionConf.keyField) || isNotEmpty(obj[actionConf.keyField]))
                    )
                )) {
                    if (isUndefined(obj.lineKey)) {
                        obj.lineKey = obj.key;
                    }
                    reData.push(obj);
                }
            });
        }

        return reData;
    }

    /**
     * 获取不为空的数据
     * @param onlyChange {boolean} 是否只获取改变了的数据。默认 false
     * @return {*[]}
     */
    getDataNoEmpty(onlyChange = true) {
        return this.getAjaxData(onlyChange, { noEmpty: true });
    }

    /**
     * 获取删除了的记录
     * @param fullRecord boolean 是否需要返回完整的记录。默认 false，只返回删除了的 id 数组
     * @return {[]}
     */
    getDeleted(fullRecord = false) {
        if (!fullRecord) {
            return this.deletedIds;
        }
        let reData = [];

        forEach(this.state.dataSource, (dataItem) => {
            if (dataItem && -1 !== indexOf(this.deletedIds, dataItem.id)) {

                if (fullRecord) {
                    reData.push(dataItem);
                } else {
                    reData.push(dataItem.id);
                }
            }
        });

        return reData;
    }

    /**
     * 表格是否有变化
     * @return {boolean}
     */
    hadChanged() {
        let changed = false;

        forEach(this.state.dataSource, (dataItem) => {

            if (dataItem.CHANGED || this.changedRecords[dataItem.key]) {
                changed = true;
                return false;
            }
        });

        if (!changed) {
            forEach(this.state.propData, (dataItem) => {
                if (dataItem && -1 !== indexOf(this.deletedIds, dataItem.id)) {
                    changed = true;
                    return false;
                }
            });
        }

        return changed;
    }

    /**
     * 调整列宽的回调
     * @param index
     */
    handleResize = (index, column) => (e, data) => {
        e.stopPropagation();
        e.preventDefault();
        // console.log('handleResize size', size);
        const { onResize, needNO } = this.props;
        // const {columns} = this.state;
        const { size } = data;
        const tfootRef = this.tfootRef;
        const tfRefCur = tfootRef.current;
        // const nextColumns = [...columns];
        let wInd = index;

        if (wInd > -1) {
            // 记录拖拽改变了的列宽
            this.resizingColsW[`_${column.dataIndex}`] = size.width;

            // nextColumns[wInd] = {
            //     ...nextColumns[wInd],
            //     width: size.width
            // };
            this.setState({
                randomKey: getRandomKey(),
                // columns: nextColumns
            });

            // 调整列宽时，同时调整 tfoot 的
            if (tfRefCur && isFunction(tfRefCur.handleResize)) {
                tfRefCur.handleResize(data, wInd);
            }

            onResize && onResize(data, wInd);
        }
    };

    /**
     * 保存某单元格的值
     * @param value
     * @param dataIndex
     * @param rowIndex
     * @param oldRecord
     * @param afterCb
     */
    handleSave = (value, dataIndex, rowIndex, oldRecord, afterCb) => {
        // console.log('handleSave');
        const { onCellUpdate } = this.props;
        let hadCellCb = isFunction(onCellUpdate);
        let prevChangedRecord = this.changedRecords[oldRecord.key] || oldRecord;

        let item = { ...prevChangedRecord, CHANGED: true };
        // 如果 item 只有 key、lineKey、CHANGED 属性，说明是这是条空记录
        // 则调用 getDefaultRecord() 获取默认的记录
        if (isEmpty(omit(item, [...defaultFields, 'CHANGED']))) {
            item = { ...this.getDefaultRecord(item), ...item };
        }

        item[dataIndex] = value;

        if (hadCellCb) {

            let newItem = onCellUpdate(dataIndex, item, prevChangedRecord, rowIndex, {
                list: this.state.dataSource,
            });

            if (false === newItem) return false;

            if (isObject(newItem) && !isEmpty(newItem)) {
                item = newItem;
            }
        }

        this.changedRecords[item.key] = item;

        // 如果该列需要汇总，则更新底部汇总数据
        let curCol = find(this.state.columns, (col) => (
            col && col.dataIndex === dataIndex
        ));

        if (curCol && curCol.sum && this.tfootRef && isFunction(this.tfootRef.current.setSumByCol)) {
            this.tfootRef.current.setSumByCol(this._calcColSum(curCol, true), dataIndex);
        }

        if (hadCellCb) {
            // 如果表格含有当前 dataIndex 字段的嵌套字段需要显现（例如: dataIndex == 'finder'，然后表格含有'finder.name'列）、
            // 或者有其他字段更新，则重新渲染表格
            let omitArr = [dataIndex, 'CHANGED'];
            if (hadInnerDataIndex(this.state.columns, dataIndex) || !isObjectValEqual(omit(prevChangedRecord, omitArr), omit(item, omitArr))) {
                // console.log(`'${dataIndex}' change`);
                const newList = [...this.state.dataSource];
                const inListInd = findIndex(newList, (listItem) => (listItem && listItem.key === item.key));
                if (-1 < inListInd) {
                    // --------------------------
                    /**
                     * 给记录添加一个随机数字段(RANDOM)，用于强制更新此行的单元格
                     * 用于修复此bug：可编辑表格的联动bug。
                     *      第一次联动起效，之后的联动就不起效了。
                     *      例如（会计规则：切换“因素位置”自动清空“金额字段”->切换“因素位置”->选择“金额字段”->切换“因素位置”就不起效了）
                     * @type {string}
                     */
                    item.RANDOM = getRandomKey();
                    //----------------------------

                    newList[inListInd] = item;
                }
                this.setDataSource(newList, afterCb);
                return item;
            }
        }
        afterCb && afterCb();
        return item;
    };

    // /**
    //  * 将编辑的单元格滚动给到可见区域
    //  * @param offsetLeft
    //  */
    // scroll2View(offsetLeft) {
    //     // const {l, r} = this.props;
    //     // 将编辑的单元格滚动给到可见区域
    //     if (this.tableBody && isNumber(offsetLeft) && isFunction(this.tableBody.scrollBy)) {
    //         const scrollLeft = this.tableBody.scrollLeft;
    //         const tOffsetWidth = this.tableBody.offsetWidth;
    //         const scrollWidth = this.tableBody.scrollWidth;
    //         console.log('scroll2View', offsetLeft, scrollLeft, tOffsetWidth, scrollWidth);
    //         if (offsetLeft - scrollLeft > 400) {
    //             this.tableBody.scrollBy(offsetLeft - scrollLeft - 400, 0);
    //         } else if (offsetLeft - scrollLeft < 200) {
    //             this.tableBody.scrollBy(-(200 - offsetLeft + scrollLeft), 0);
    //         }
    //     }
    // }

    /**
     * 将编辑的单元格滚动给到可见区域
     * @param target {HTMLElement} 单元格 dom 元素
     */
    scroll2View(target) {
        scroll2View(this.tableBody, target, this.lFixedW, this.rlFixedW);
    }

    /**
     * 删除多行
     * @param rowKeys string[]
     * @param afterCb
     */
    deleteRows(rowKeys, afterCb = null) {
        const data = this.state.dataSource;
        let tempArr = filter(data, o => {

            if (-1 === indexOf(rowKeys, o.key)) {
                return true;

            } else {
                // 记下删除了的记录
                if (o && o.id) {
                    this.deletedIds.push(o.id);
                }
                return false;
            }
        });

        const { onRowUpdate } = this.props;
        if (isFunction(onRowUpdate)) {
            let newData = onRowUpdate({
                type: TableBarActions.delete,
                dataList: tempArr,
                preDataList: data,
                deleteIds: this.deletedIds,
            });
            if (false === newData) return false;

            if (isArray(newData)) {
                tempArr = newData;
            }
        }
        this.setDataSource(tempArr, afterCb);
    }

    /**
     * 筛选表格数据。支持筛选所有列的展示数据
     * @param search {string} 搜索的文本
     */
    searchInTable(search) {
        // console.log('searchInTable');
        this.search = search;
        let needForceRender = isEmpty(this.changedRecords);
        this.setDataSource(this.state.dataSource, () => {
            needForceRender && this.reRender();
        });
    }

    /**
     * 表内过滤
     * @return {[]|*}
     */
    filterDataSource() {
        let newList = [];
        let sTxt = trim(this.search);

        if (isEmpty(sTxt)) {
            newList = this.state.dataSource;

        } else {
            const currentList = this.state.dataSource;

            forEach(currentList, (item, ind) => {
                let isOk = false;

                forIn(item, (val) => {
                    if (((isNumber(val) || isString(val)) && `${val}`.indexOf(sTxt) > -1)
                        || (val && isObject(val) && (
                            `${val.name}`.indexOf(sTxt) > -1 || `${val.code}`.indexOf(sTxt) > -1
                        ))) {
                        isOk = true;
                        return false;
                    }
                });
                if (isOk) {
                    // console.log('ind', ind);
                    newList.push(item);
                }
            });
        }

        return newList;
    }

    editRow(key, newCol = undefined) {
        // console.log('editRow', key);
        const { getDefaultRecord, onRowUpdate, canSort } = this.props;
        const { dataSource, columns } = this.state;
        const editingRow = this.focusRow;
        const data = dataSource;
        let curIndex = findIndex(data, (dataItem) => (dataItem && dataItem.key === editingRow));
        let record = data[curIndex];
        let newFocusRow;
        let newRecord;

        if (record && this.changedRecords[record.key]) {
            record = { ...(record || {}), ...this.changedRecords[record.key] };
        }

        if (isEmpty(record)) {
            record = isFunction(getDefaultRecord) ? getDefaultRecord({ ...record }) : genRecordByCols(columns);
        }

        let len = data.length,
            tempArr = [...data],
            setArrInd = (arr, ind1, ind2) => {
                if (arr[ind2]) {
                    arr[ind1] = { ...arr[ind1], CHANGED: true };
                    arr[ind2] = { ...arr[ind2], CHANGED: true };

                    let order1 = arr[ind1].order;
                    arr[ind1].order = arr[ind2].order;

                    let tmpO = arr.splice(ind2, 1, arr[ind1])[0];
                    tmpO.order = order1;

                    if (this.changedRecords[tmpO.key]) this.changedRecords[tmpO.key].order = tmpO.order;
                    if (this.changedRecords[arr[ind1].key]) this.changedRecords[arr[ind1].key].order = arr[ind1].order;

                    return tmpO;
                } else {
                    return arr[ind1];
                }
            };

        if (TableBarActions.add === key || key === TableBarActions.insert) {
            newRecord = isFunction(getDefaultRecord) ? getDefaultRecord({ ...record }) : genRecordByCols(columns);

            if (!isObject(newRecord) || isEmpty(newRecord)) {
                newRecord = genRecordByCols(columns);
            }
            if ('undefined' === typeof newRecord.key) {
                newRecord.key = getRandomKey();
                newRecord.linKey = newRecord.key;
            }

            newFocusRow = newRecord.key;

            newRecord = { ...newRecord, CHANGED: true };

            if (TableBarActions.add === key) {
                // 设置顺序（order）字段
                let order = 1;
                let tmpRecord = tempArr[len - 1];
                if (tmpRecord && tmpRecord.order > 0) {
                    order = parseFloat(tmpRecord.order) + 1;
                }
                newRecord.order = order;
                newRecord.showOrder = order;
                tempArr.push(newRecord);
                // tempArr.splice(curIndex + 1, 0, newRecord);

            } else { // 插入行（往下）
                // 设置顺序（order）字段
                let order = 1;
                let curRecord = data[curIndex];
                let nextRecord = data[curIndex + 1];

                if (curRecord && curRecord.order > 0) {
                    if (nextRecord && nextRecord.order > 0) {
                        order = (parseFloat(nextRecord.order) + parseFloat(curRecord.order)) / 2;
                    } else {
                        order = parseFloat(curRecord.order) + 1;
                    }
                }
                newRecord.order = order;
                newRecord.showOrder = order;
                tempArr.splice(curIndex + 1, 0, newRecord);
            }
            record = newRecord;

        } else if (TableBarActions.delete === key && curIndex > -1) {

            tempArr = filter(data, o => o.key !== record.key);

            if (isEmpty(tempArr[curIndex])) {
                newFocusRow = tempArr[curIndex - 1] ? tempArr[curIndex - 1].key : (tempArr[0] ? tempArr[0].key : '');
            } else {
                newFocusRow = tempArr[curIndex].key;
            }

        } else if (TableBarActions.up === key) { // 上移
            if (!canSort) return false;

            if (curIndex > 0 && curIndex < len) {
                // debugger;
                newFocusRow = tempArr[curIndex] ? tempArr[curIndex].key : '';

                tempArr[curIndex] = setArrInd(tempArr, curIndex, curIndex - 1);
            }
        } else if (TableBarActions.down === key) { // 下移
            if (!canSort) return false;

            if (curIndex > -1 && curIndex < len - 1) {
                newFocusRow = tempArr[curIndex] ? tempArr[curIndex].key : '';

                tempArr[curIndex] = setArrInd(tempArr, curIndex, curIndex + 1);
            }

        } else if (TableBarActions.sort === key) { // 刷新排序
            tempArr = map(tempArr, (v, k) => {
                if (v && (v.order !== k + 1 || (
                    v.hasOwnProperty('showOrder') && v.showOrder !== k + 1
                ) || (
                    v.hasOwnProperty('sortOrder') && v.sortOrder !== k + 1
                ))) {
                    return { ...v, order: k + 1, showOrder: k + 1, sortOrder: k + 1, CHANGED: true };
                } else {
                    return v;
                }
            });
        }

        if (isFunction(onRowUpdate)) {
            let newData = onRowUpdate({
                type: key,
                record: record,
                rowIndex: tempArr[curIndex] ? tempArr[curIndex].key : '',
                dataList: tempArr,
                preDataList: data,
                deleteIds: record && record.id > 0 ? [...this.deletedIds, record.id] : this.deletedIds,
            });
            if (false === newData) return false;

            if (isArray(newData)) {
                tempArr = newData;
            }
        }

        if (TableBarActions.delete === key && record && record.id) {
            this.deletedIds.push(record.id);
        }

        // console.log('tempArr', tempArr);

        this.setDataSource(tempArr, () => {

            if ('undefined' !== typeof newFocusRow) {
                this.setFocusRow(newFocusRow, newFocusRow === this.focusRow);

                let row1 = this.focusRow, col1 = undefined !== newCol ? newCol : this.editingCell.col;

                if (TableBarActions.up === key || TableBarActions.down === key) {
                    this.setFocusCell({ row: row1, col: col1 }, newFocusRow === this.focusRow);
                } else {
                    this.setFocusCell({ row: row1, col: col1 });
                }
            }
        });

    }

    /**
     * 判断当前 单元格是否可编辑
     * */
    _isCurCellEditable() {
        const tmpCellRef = this.editableCellRefs[genCellRefKey(this.editingCell)];
        return tmpCellRef && tmpCellRef.props && tmpCellRef.props.editable;
    };

    /**
     * 编辑上一行当前列单元格
     */
    editUp() {
        // 判断是否有上一个可编辑的单元格
        const { autoAdd } = this.props;
        const $this = this;
        let rowInd = findIndex(this.state.dataSource, (dataItem) => dataItem && dataItem.key === this.focusRow);

        if (-1 !== rowInd) {
            let prevRow = rowInd - 1;
            let prevRecord = $this.state.dataSource[prevRow];

            if (prevRecord) {
                this.setFocusRow(prevRecord.key);
                this.setFocusCell({ row: prevRecord.key, col: this.editingCell.col });

                if (!this._isCurCellEditable()) {
                    this.editUp();
                }
            }

        } else {
            if (autoAdd) {
                this.editRow(TableBarActions.insert);
            }
        }
    }

    /**
     * 编辑下一行当前列单元格
     */
    editDown() {
        // 判断是否有下一个可编辑的单元格
        const { autoAdd } = this.props;

        let rowInd = findIndex(this.state.dataSource, (dataItem) => dataItem && dataItem.key === this.focusRow);

        if (-1 !== rowInd) {
            let nextRow = rowInd + 1;
            let nextRecord = this.state.dataSource[nextRow];

            if (nextRecord) {
                this.setFocusRow(nextRecord.key);
                this.setFocusCell({ row: nextRecord.key, col: this.editingCell.col });

                if (!this._isCurCellEditable()) {
                    this.editDown();
                }
            }

        } else {
            // 如果允许自动添加行，则往下添加一行
            if (autoAdd) {
                this.editRow(TableBarActions.add);
            }
        }
    }

    /**
     * 编辑上一个单元格
     */
    editPrev(offsetLeft) {
        // console.log('editPrev');
        const $this = this;
        // 左移判断是否有上一个 可编辑单元格
        let prevCol;
        const curColInd = $this.editableCols.indexOf($this.editingCell.col);

        if (-1 !== curColInd) {
            prevCol = $this.editableCols[curColInd - 1];
        }

        // 如果有，就将上一个单元格改为可编辑状态
        if ('undefined' !== typeof prevCol && null !== prevCol) {

            $this.setFocusCell({ col: prevCol, row: this.editingCell.row });

            if (!this._isCurCellEditable()) {
                this.editPrev(offsetLeft);
            }

        } else {
            //如果没有，则往上一行
            let rowInd = findIndex(this.state.dataSource, (dataItem) => dataItem && dataItem.key === this.focusRow);
            const prevRow = rowInd - 1;
            let prevRowKey = this.state.dataSource[prevRow] ? this.state.dataSource[prevRow].key : '';

            if (prevRow !== -1) {
                //往上一行， 最后一列
                this.setFocusRow(prevRowKey);
                this.setFocusCell({ row: prevRowKey, col: this.editableCols[this.editableCols.length - 1] });
                // 如果下一个单元格不可编辑，则继续到“下一个可编辑单元格”
                if (!this._isCurCellEditable()) {
                    this.editPrev(offsetLeft);

                } else {
                    // 横向滚动到最右边
                    if (this.tableBody) {
                        this.tableBody.scrollLeft = 1000;
                    }
                }

            }
        }

    }

    /**
     * 编辑下一个单元格
     */
    editNext(offsetLeft) {
        // console.log('editNext');
        // 判断是否有下一个可编辑单元格，
        const { getDefaultRecord, autoAdd } = this.props;
        const $this = this;
        let nextCol;
        const curColInd = $this.editableCols.indexOf($this.editingCell.col);

        if (-1 !== curColInd) {
            nextCol = $this.editableCols[curColInd + 1];
        }
        // 如果有，就将下一个单元格改为编辑状态
        if ('undefined' !== typeof nextCol && null !== nextCol) {

            $this.setFocusCell({ col: nextCol, row: this.editingCell.row });
            // 如果当前单元格不可编辑，则找下一个
            if (!$this._isCurCellEditable()) {
                $this.editNext(offsetLeft);
            }

        } else {
            // 如果没有下一个单元格，则往下一行
            let rowInd = findIndex(this.state.dataSource, (dataItem) => (dataItem && dataItem.key === this.focusRow));
            const nextRow = rowInd + 1;

            // 没有下一行
            if (isEmpty(this.state.dataSource[nextRow])) {
                // 如果可以自动添加，则添加一行；否则，取消编辑状态
                if (autoAdd) {
                    // 横向滚动到最左边
                    if (this.tableBody) {
                        this.tableBody.scrollLeft = 0;
                    }
                    // 添加一行
                    this.editRow(TableBarActions.add, this.editableCols[0]);

                } else {
                    // 取消编辑状态
                    this.setFocusCell({ row: '', col: '' });
                }

            } else {
                // 有下一行
                let nextRowKey = this.state.dataSource[nextRow].key;
                const curRowRecord = this.state.dataSource[rowInd] || {};
                const newState = {};

                let newRecord = this.getDefaultRecord(curRowRecord);
                newRecord.key = nextRowKey;

                // 如果下一行的对象值为空，则设置默认值
                if (isObjectValueEmpty(omit(this.state.dataSource[nextRow], [...defaultFields, 'id']))) {
                    newState.dataSource = [...$this.state.dataSource];
                    newState.dataSource[nextRow] = newRecord;
                }

                $this.setState(newState, () => {
                    this.setFocusRow(nextRowKey);
                    // 下一行的第一个可编辑单元格
                    this.setFocusCell({ row: nextRowKey, col: $this.editableCols[0] });
                    // 如果下一个单元格不可编辑，则继续到“下一个可编辑单元格”
                    if (!this._isCurCellEditable()) {
                        this.editNext(offsetLeft);

                    } else {
                        // 横向滚动到最左边
                        if (this.tableBody) {
                            this.tableBody.scrollLeft = 0;
                        }
                    }
                });
            }
        }
    }

    setDataSource(newDataSource, afterCb) {
        // debugger
        if (!isEmpty(this.changedRecords)) {
            const newData = map(newDataSource, (dataItem) => {
                if (this.changedRecords[dataItem.key]) {
                    return { ...dataItem, ...this.changedRecords[dataItem.key] };
                } else {
                    return dataItem;
                }
            });
            this.setState({ dataSource: newData }, () => {
                this.changedRecords = {};
                isFunction(afterCb) && afterCb();
            });
        } else {
            this.setState({ dataSource: newDataSource }, afterCb);
        }
    }

    setFocusRow(nextRowKey, value = false) {
        // console.log('setFocusRow', nextRowKey, value)
        let rowRef = this.rowRefs[this.focusRow];

        if (rowRef && rowRef.setFocus) {
            let isFocus = this.focusRow === nextRowKey;
            rowRef.setFocus(isFocus, () => {
                if (isFocus) {
                    const onRowFocus = this.getPropsByName('onRowFocus');
                    if (isFunction(onRowFocus)) {
                        onRowFocus(recursiveFind(this.state.dataSource, (obj) => (obj && obj.key === this.focusRow)));
                    }
                }
            });
        }

        if (this.focusRow !== nextRowKey) {
            this.focusRow = nextRowKey;
            this.setFocusRow(nextRowKey, true);
        }
    }

    /**
     * 聚焦到某个单元格
     * @param rowCol {{row: string, col: string}} 聚焦的行列。row：行的 key。col： 列的 dataIndex
     * @param editing {boolean} 是否正在编辑
     * @param afterCb
     */
    setFocusCell({ row, col }, editing = false, afterCb = null) {
        let cellRef = this.editableCellRefs[genCellRefKey(this.editingCell)];

        if (cellRef && cellRef.setFocus) {
            cellRef.setFocus(editing, afterCb);
            // const {onFocus}
        }

        if (this.editingCell.row !== row || this.editingCell.col !== col) {
            this.editingCell.row = row;
            this.editingCell.col = col;
            this.setFocusCell(this.editingCell, true);
        }

    }

    /**
     * 计算某一列的汇总数
     * @param col object 某一列的配置
     * @param needMergeChanged boolean 是否需要合并已改变的单元格；默认：false
     * @return {any}
     * @private
     */
    _calcColSum(col, needMergeChanged = false) {
        let sumValue = 0;
        let dataSrc = this.state.dataSource;

        if (needMergeChanged) {
            dataSrc = map(this.state.dataSource, (dataItem) => {
                if (this.changedRecords[dataItem.key]) {
                    return { ...dataItem, ...this.changedRecords[dataItem.key] };
                } else {
                    return dataItem;
                }
            });
        }

        forEach(dataSrc, (dataItem) => {
            if (dataItem && dataItem[col.dataIndex]) {
                sumValue = jhAdd(sumValue, dataItem[col.dataIndex]);
                // sumValue += parseFloat(dataItem[col.dataIndex]) || 0;
            }
        });
        return sumValue; //fuckJsFloat(sumValue, col.floatNum > 0 ? col.floatNum : 0);
    }

    saveCell = (e, record, col, afterCb) => {

        if (e && e.preventDefault) {
            e.preventDefault();
            e.stopPropagation();
        }

        // console.log('saveCell');
        const $this = this;
        const keyStr = genCellRefKey({ row: record.key, col: col.dataIndex });
        const tmpCellRef = $this.editableCellRefs[keyStr];

        if (tmpCellRef && isFunction(tmpCellRef.save)) {
            let offSetLeft;

            if (e && e.currentTarget) {
                offSetLeft = e.currentTarget.offsetLeft;
            }
            tmpCellRef.save(e, () => {
                let offLeft = isEmpty(col.fixed) ? offSetLeft + this.lFixedW : 0;
                isFunction(afterCb) && afterCb(offLeft);
            });
        }
    };

    lFixedW = 0; // 左侧冻结的尺寸（px）
    rlFixedW = 0; // 右侧冻结的尺寸（px）

    /**
     * 计算横向滚动的宽度 scroll.x
     * @param scrollObj
     * @param fixed
     * @param width
     * @return {TableBase._calcScrollX.props|{x: number}}
     * @private
     */
    _calcScrollX(scrollObj, { fixed, width, dataIndex }) {
        let colW = this.resizingColsW[`_${dataIndex}`] || width;
        let w = 150;

        if (isString(colW)) {
            if (-1 === colW.indexOf('%')) {
                w = parseInt(colW) || 150;
            }
        } else if (isNumber(colW)) {
            w = colW;
        }

        if (!isObject(scrollObj)) {
            scrollObj = { x: 0 };
        }
        if (!isNumber(scrollObj.x)) {
            scrollObj.x = 0;
        }
        scrollObj.x += w;

        // 计算冻结列占的宽度
        if ('left' === fixed) {
            this.lFixedW += w;
        } else if ('right' === fixed) {
            this.rlFixedW += w;
        }

        return scrollObj;
    }

    mainRender(context) {
        let {
            fieldEnabledObj,
            needNO, pagination, onResize, sumData, rowSelect, scroll, style = {}, appins, onRowProps,
            ...restProps
        } = this.props;
        if (!isObject(fieldEnabledObj)) fieldEnabledObj = {};
        const { columns } = this.state;
        const dataSource = this.filterDataSource();

        this.editableCols = [];
        let editableCols = this.editableCols;
        let editableCellRefs = this.editableCellRefs;
        let rowRefs = this.rowRefs;
        let editingCell = this.editingCell;
        let dataLength = dataSource.length;

        let moreProps = {
            scroll: !isEmpty(scroll) ? { ...scroll } : ('auto' === style.height ? {} : { y: 300 }),
            style: {
                ...style,
                height: style.height ? style.height : 75,
            },
        };
        let paginationProps = false === pagination ? false : {
            size: 'small',
            showSizeChanger: false,
            showLessItems: true,
            showTotal: (total, range) => `${this.myFormatMessage('comp.page.showTotalSize', {
                total, range0: range[0], range1: range[1],
            })}`,
            pageSize: 40,
            ...pagination,
        };
        // 标识是不是单页展示大量数据
        let isBigDataPerPage = (dataLength > 100 && paginationProps === false);

        let current = null;
        let pageSize = null;

        if (paginationProps) {
            current = paginationProps.current;
            pageSize = paginationProps.pageSize;
        }

        let tmpSumData = [];
        let newCols = columns;
        if (needNO && columns && columns[0] && 'NO' === columns[0].dataIndex) {
            newCols = [...columns];
            newCols[0].render = (value, record, rowInd) => {
                if (record.IS_SUM) return null; // 合计行不显示序号

                if (current && pageSize) {
                    return (current - 1) * pageSize + rowInd + 1;
                } else {
                    return rowInd + 1;
                }
            };
        }

        this.lFixedW = isCurModernBrowser && rowSelect ? 50 : 0; // 左侧冻结的尺寸（px）
        this.rlFixedW = 0; // 右侧冻结的尺寸（px）

        // 取消上一个“选定单元格”
        const unFocusCurrent = () => {
            let tmpKey = genCellRefKey(editingCell);

            if (editableCellRefs[tmpKey] && editableCellRefs[tmpKey].setFocus) {
                editableCellRefs[tmpKey].setFocus(false);
            }
            editingCell.row = '';
            editingCell.col = '';
        };

        const cols = recursiveMap(newCols, (colItem, colIndex, parentObj) => {
            const col = { ...colItem, fixed: isCurModernBrowser && colItem.fixed || '' };
            const { editable, editingSetting, sum, fieldCtrl } = col;
            let cellExtraProps = {};

            if (true !== editable) { // 不可编辑
                cellExtraProps.onCell = (record) => (
                    {
                        ...(col.cellProps || {}),
                        renderFunc: col.render,
                        record,
                        dataIndex: col.dataIndex,
                        title: col.title,
                        componentType: col.componentType,
                        editable: false,
                        fieldCtrl,
                    }
                );

            } else { // 可编辑
                cellExtraProps.onCell = (record, rowIndex) => {
                    let rowInd = findIndex(dataSource, (dataItem) => (dataItem && dataItem.key === record.key));
                    // 如果 record.noEditable === true ，
                    //      或者 props.fieldEnabledObj[dataIndex] 是个 function，且执行结果===false，
                    //      或者 record.editableCols 不为空，且 col.dataIndex 不在其中，
                    //      或者 record.disabledCols 不为空，且 col.dataIndex 在其中
                    // 则此单元格不可编辑
                    let noEditable;

                    if (isFunction(fieldEnabledObj[col.dataIndex])) {
                        noEditable = fieldEnabledObj[col.dataIndex](record || {}) === false;
                    } else {
                        noEditable = record && (record['noEditable'] ||
                            (!isEmpty(record.editableCols) && -1 === indexOf(record.editableCols, col.dataIndex)) ||
                            (!isEmpty(record.disabledCols) && -1 < indexOf(record.disabledCols, col.dataIndex))
                        );
                    }

                    if (noEditable) {
                        return {
                            record,
                            renderFunc: col.render,
                            // rowIndex: rowInd,
                            dataIndex: col.dataIndex,
                            componentType: col.componentType,
                            title: col.title,
                            editable: false,
                            fieldCtrl,
                            ...(col.cellProps || {}),
                        };
                    }
                    return {
                        ...(col.cellProps || {}),
                        record,
                        rowIndex: rowInd,
                        renderFunc: col.render,
                        dataIndex: col.dataIndex,
                        key: col.dataIndex,
                        componentType: col.componentType,
                        editable,
                        editingSetting,
                        fieldCtrl,
                        onSave: this.handleSave.bind(this),
                        scroll2View: this.scroll2View.bind(this),
                        prevFunc: () => {
                            this.saveCell(null, record, col, offLeft => {
                                this.editPrev(offLeft);
                            });
                        },
                        nextFunc: () => {
                            this.saveCell(null, record, col, offLeft => {
                                this.editNext(offLeft);
                            });
                        },
                        onRef: (ref) => {

                            if (editable) {
                                editableCellRefs[genCellRefKey({ row: record.key, col: col.dataIndex })] = ref;
                            }
                        },
                        onClick: (e, curRecord) => {
                            // console.log('onCell onClick');
                            // 取消上一个“选定单元格”，然后标识"选定当前单元格 editingCell"
                            if (curRecord.key !== editingCell.row || col.dataIndex !== editingCell.col) {
                                let tmpKey = genCellRefKey(editingCell);

                                if (editableCellRefs[tmpKey] && editableCellRefs[tmpKey].setFocus) {
                                    editableCellRefs[tmpKey].setFocus(false);
                                }
                            }
                            editingCell.row = curRecord.key;
                            editingCell.col = col.dataIndex;
                            // 取消上一个“选定的行”，选定当前行
                            this.setFocusRow(curRecord.key);
                        },
                        onKeyDown: (e) => {
                            const $this = this;
                            let keyCode = e.keyCode || e.charCode;
                            let shiftKey = e.shiftKey;
                            let altKey = e.altKey;

                            if (keyCodes.tab === keyCode || altKey) {
                                e.preventDefault();
                                e.stopPropagation();
                            }

                            // shift + alt
                            if (shiftKey && altKey) {
                                // shift+alt+down 添加
                                if (keyCodes.down === keyCode) {
                                    this.saveCell(e, record, col, () => {
                                        $this.editRow(TableBarActions.insert);
                                    });
                                }
                            }
                            // shift +
                            else if (shiftKey) {
                                // shift+backspace shift+delete 删除当前行
                                if ((keyCodes.backspace === keyCode || keyCodes.del === keyCode) && false !== this.getPropsByName('canDel')) {
                                    e.preventDefault();
                                    e.stopPropagation();
                                    $this.editRow(TableBarActions.delete);
                                }
                                // shift+up 上一行当前列单元格
                                else if (keyCodes.up === keyCode) {
                                    this.saveCell(e, record, col, () => {
                                        $this.editUp();
                                    });
                                }
                                // shift+down 下一行当前列单元格
                                else if (keyCodes.down === keyCode) {
                                    this.saveCell(e, record, col, () => {
                                        $this.editDown();
                                    });
                                }
                                // shift+tab shift+left 上一单元格
                                else if (keyCodes.tab === keyCode || keyCodes.left === keyCode) {
                                    this.saveCell(e, record, col, offLeft => {
                                        this.editPrev(offLeft);
                                    });
                                }
                                // shift+right 下一单元格
                                else if (keyCodes.right === keyCode) {
                                    this.saveCell(e, record, col, offLeft => {
                                        this.editNext(offLeft);
                                    });
                                }

                            }
                            // alt+
                            else if (altKey) {
                                // alt+up 当前行上移
                                if (keyCodes.up === keyCode) {
                                    this.saveCell(e, record, col, () => {
                                        $this.editRow(TableBarActions.up);
                                    });
                                }
                                // alt+down 当前行下移
                                else if (keyCodes.down === keyCode) {
                                    this.saveCell(e, record, col, () => {
                                        $this.editRow(TableBarActions.down);
                                    });
                                }
                            }
                            // enter tab 切换到下一单元格
                            else if (keyCodes.enter === keyCode || keyCodes.tab === keyCode) {
                                this.saveCell(e, record, col, offLeft => {
                                    this.editNext(offLeft);
                                });
                            }
                            // 禁止 F5 刷新
                            else if (keyCodes.f5 === keyCode) {
                                e.preventDefault();
                                e.stopPropagation();
                            }
                            // ESC 退出编辑
                            else if (keyCodes.esc === keyCode) {
                                this.saveCell(e, record, col, offLeft => {
                                    this.setFocusCell({ row: '', col: '' });
                                });
                            }
                        },
                    };
                };

                if (isEmpty(col.children)) editableCols.push(col.dataIndex);
            }

            // 列宽
            if (this.resizingColsW[`_${col.dataIndex}`]) {
                cellExtraProps.width = this.resizingColsW[`_${col.dataIndex}`];
            }

            // 需要汇总的列，计算列总和
            if (sum) {
                let sumValue = this._calcColSum(col);

                if ('undefined' === typeof tmpSumData[0]) {
                    let firstDataIndex = needNO ? (
                        newCols[1] ? newCols[1]['dataIndex'] : ''
                    ) : (
                        newCols[0] ? newCols[0]['dataIndex'] : ''
                    );
                    tmpSumData[0] = { IS_SUM: true };

                    if (firstDataIndex) {
                        tmpSumData[0][firstDataIndex] = this.formatMsgByCn('合计');
                    }
                }
                tmpSumData[0][col.dataIndex] = sumValue;
            }

            // 表宽
            moreProps.scroll = this._calcScrollX(moreProps.scroll, col);

            return {
                ...col,
                onHeaderCell: column => {
                    const reObj = {
                        width: column.width,
                        colInd: colIndex,
                        fixed: column.fixed,
                        isBig: isBigDataPerPage,
                        rowSelect: isCurModernBrowser && rowSelect,
                        fieldCtrl: col.fieldCtrl,
                    };
                    // 如果是单页展示大量数据，则在调整表头列宽的动作结束之后（onResizeStop)，再调整表身列宽
                    // 否则，调整表头列宽期间（onResize），同时调整表身列宽
                    if (isBigDataPerPage) {
                        reObj.onResizeStop = this.handleResize(colIndex, column);
                    } else {
                        reObj.onResize = this.handleResize(colIndex, column);
                    }
                    return reObj;
                },
                ...cellExtraProps,
            };
        });

        // 行
        moreProps.onRow = (record) => ({
            record,
            onRef: (ref) => {
                rowRefs[record.key] = ref;
            },
            onClick: (e, curRecord) => {
                // 取消上一个“选定的行”
                if (curRecord.key !== this.focusRow && rowRefs[this.focusRow] && rowRefs[this.focusRow].setFocus) {
                    rowRefs[this.focusRow].setFocus(false);
                }
                this.focusRow = curRecord.key;

                if (onRowProps && isFunction(onRowProps.onClick)) {
                    onRowProps.onClick(e, curRecord);
                }
            },
            onDoubleClick: (e, curRecord) => {

                if (onRowProps && isFunction(onRowProps.onDoubleClick)) {
                    onRowProps.onDoubleClick(e, curRecord);
                }
            },
        });

        // 底部汇总行
        let finalSumData = [];
        if (!isEmpty(sumData)) {
            finalSumData = sumData;

        } else if (!isEmpty(tmpSumData)) {
            finalSumData = tmpSumData;
        }
        if (!isEmpty(finalSumData)) {
            moreProps.summary = (currentData) => {
                return <SumRow
                    ref={this.tfootRef}
                    dataSource={finalSumData}
                    currentData={currentData}
                    columns={cols}
                    rowSelect={isCurModernBrowser && rowSelect}
                />;
            };
        }

        // console.log('moreProps.scroll', moreProps.scroll);
        // 如果有勾选列，则 scroll.x 添加 50
        if (this.props.rowSelect && moreProps.scroll && moreProps.scroll.x) {
            moreProps.scroll.x += 50;
        }
        this.scrollObj = moreProps.scroll;

        return (
            <div
                style={{
                    paddingBottom: false === pagination || 0 === dataLength ? 8 : 0,
                    ...moreProps.style,
                }}
                onClick={(e) => {
                    // console.log('div onClick', e.nativeEvent);
                    // 取消上一个“选定单元格”
                    unFocusCurrent();
                }}>
                <Table
                    key={this.state.tableRandomKey}
                    // bordered={false}
                    {...omit(restProps, ['colsConf', 'actionConf', 'sortConf', 'customprops', 'l', 'r', 'onRef'])}
                    {...moreProps}
                    style={{ ...moreProps.style, height: '100%' }}
                    className={`${this.tableID} ${styles.table} with-border no-padding`}
                    components={this.components}
                    pagination={paginationProps}
                    columns={cols}
                    dataSource={dataSource}
                    onChange={(pagination, filters, sorter, moreData) => {
                        // sorter 的数据结构：
                        //  column: {remark: "金额", name: "amount", floatNum: 2, sum: true, reg: "", …}
                        //  columnKey: "amount"
                        //  field: "amount"
                        //  order: "ascend"
                        const { currentDataSource } = moreData;

                        // 如果有分页的话，则每次表格有变化时，
                        //  将有 changedRecords 更新到 state.dataSource
                        if (false !== paginationProps ||
                            !isEqual(currentDataSource, this.state.dataSource) ||
                            !isEmpty(this.changedRecords)
                        ) {
                            this.setDataSource(this.state.dataSource, () => {
                                isFunction(this.props.onChange) && this.props.onChange(pagination, filters, sorter, moreData);
                            });
                        } else {
                            isFunction(this.props.onChange) && this.props.onChange(pagination, filters, sorter, moreData);
                        }
                    }}
                />
            </div>
        );
    }

}